﻿using System;

namespace Basmus.ReadWrite
{
    public class ReadResult
    {
        public bool Successful { get; private set; }

        public Type ResultType { get; private set; }

        public object Result { get; private set; }

        protected ReadResult(bool successful, Type resultType, object result)
        {
            Successful = successful;
            ResultType = resultType;
            Result = result;
        }

        public static ReadResult Success(object result, Type resultType)
        {
            var parceResult = new ReadResult(true, resultType, result);
            return parceResult;
        }

        public static ReadResult Error(object result, Type resultType)
        {
            var parceResult = new ReadResult(false, resultType, result);
            return parceResult;
        }

        public override int GetHashCode()
        {
            var hash = Successful.GetHashCode() ^ ResultType.GetHashCode();
            if (Result != null)
            {
                hash = hash ^ Result.GetHashCode();
            }
            return hash;
        }

        public override bool Equals(object obj)
        {
            var readResult = (ReadResult) obj;
            if (readResult==null)
                return false;
            if (readResult.Successful!=Successful)
                return false;
            if (readResult.ResultType!=ResultType)
                return false;
            if (readResult.Result == null && Result == null)
                return true;
            if (readResult.Result == null || Result == null)
                return false;
            return (readResult.Result.Equals(Result));
        }
    }


    public class ReadResult<TValue> : ReadResult
    {
        public TValue Value
        {
            get { return (TValue)Result; }
        }

        protected ReadResult(bool successful, TValue value)
            : base(successful, typeof(TValue), value)
        {

        }

        public static ReadResult<TValue> Success(TValue value)
        {
            var parceResult = new ReadResult<TValue>(true, value);
            return parceResult;
        }

        public static ReadResult<TValue> Error()
        {
            var parceResult = new ReadResult<TValue>(false, default(TValue));
            return parceResult;
        }


    }
}
